package tech.aistar.day02;

/**
 * 本类用来演示: 循环语句练习
 *
 * @author: success
 * @date: 2022/7/19 9:49 上午
 */
public class ForDemo {
    public static void main(String[] args) {

        // + 是java中唯一重载的运算符
        System.out.println(3+2+""+3+3);// 533

        printNine();

        System.out.println(printCount(12312));

        System.out.println(sort(123));

        System.out.println(commonDivisor2(12, 20));

        System.out.println(commonBei(12, 20));

        testThree();

        System.out.println(toBinaryMath(15));
    }

    /**
     * 用一个for实现九九乘法表 - for循环的复合形态
     */
    public static void printNine(){
        for(int i=1,j=1;i<=9;j++){
            System.out.printf("%d*%d=%d\t",i,j,i*j);
            //当行和列相同的时候,需要换行
            if(i==j){
                System.out.println();//换行
                i++;
                j=0;
            }
        }
    }

    /**
     * 传入一个数字,返回这个数字是几位数
     * @param n
     * @return
     *
     * 132/10 = 13
     * 13/10 = 1
     * 1/10 = 0
     *
     * while循环应用场景 - 当你不知道循环次数,但是知道循环结束的条件.
     *
     */
    public static int printCount(int n){
        //1. 定义一个计数器
        int count = 0;
        while(true){//死循环 - 打破循环的语句一定要存在 - break
                    //break - 打破它当前所在的那一层循环
                    //continue - 跳过本轮循环,但是会继续下一轮循环
            int result = n / 10;
            count++;
            if(result == 0)
                break;
            n = result;

        }
        return count;
    }

    /**
     * API
     * 将一个数字逆序输出
     *
     * 123 % 10  = 3
     * 123 / 10 = 12 % 10 = 2
     * 12 / 10 = 1 % 10 = 1
     * 1 / 10 = 0 => 退出条件
     *
     * @param n
     * @return
     */
    public static int sort(int n){
        int result = 0;
        while(true){
            int y = n % 10;
            int s = n / 10;
            result = result*10 + y;
            //循环退出的条件
            if(s == 0)
                break;
            n = s;
        }
        return result;
    }

    /**
     * 求俩个数的最大公约数
     * 12 % 20 = 12
     * 20 % 12 = 8
     * 12 % 8 = 4
     * 8 % 4 = 0
     * @param m
     * @param n
     * @return
     */
    public static int commonDivisor(int m,int n){
        while(true){
            int y = m % n;
            if(y == 0)
                break;
            m = n;
            n = y;
        }
        return n;
    }

    public static int commonBei(int m,int n){
       return m*n/commonDivisor(m,n);
    }

    //递归算法
    public static int commonDivisor2(int m,int n){
        //1. 出口
        if(m%n==0)
            return n;

        //2. 自己调用自己
        return commonDivisor2(n,m%n);
    }

    //for循环 - 嵌套越多,性能越低,尽量不要超过三层.
    //有一个三位数.由数字1,2,3,4组成.但是不能出现重复的数字.打印所有的组合,并且每6个换一行.
    public static void testThree(){
        //计数器
        int count = 0;

        for (int x = 1; x <=4; x++) {
            for (int y = 1; y <=4; y++) {
                for (int z = 1; z <=4; z++) {
                    //System.out.print(x+""+y+z);
                    if(x!=y && x!=z && y!=z){
                        System.out.print(x*100 + y*10 + z+"\t");
                        count++;
                        if(count==6){
                            System.out.println();
                            count = 0;
                        }
                    }
                }
            }
        }
    }

    /**
     * 输入一个正整数,返回这个正整数的二进制.比如传入数字10,返回1010
     *
     * 10 % 2 = 0
     * 10 /2 = 5
     *
     * 5 % 2 = 1
     * 5 / 2 = 2
     *
     * 2 % 2 = 0
     * 2 / 2 = 1
     *
     * 1 % 2 = 1
     * 1 / 2 = 0 => 商是0结束
     *
     * 倒过来取余数
     *
     * @param n
     * @return
     */
    public static String toBinary(int n){
        String str="";

        while(true){
            int y = n % 2;
            int s = n / 2;

            str = y + str;

            if(s == 0)
                break;

            n = s;
        }

        return str;
    }

    //听懂 -> 基本能力
    public static long toBinaryMath(int n){
        long result= 0L;

        //定义一个计数器
        int count = 0;

        while(true){
            int y = n % 2;
            int s = n / 2;
            result = (long) (y*Math.pow(10,count++) + result);   // result = 10
            if(s == 0)
                break;

            n = s;
        }
        return result;
    }
}
